package core

import (
	"bytes"
	"fmt"
	"os"
	"path"
	"sync"

	"github.com/sirupsen/logrus"
)

type MyLog struct {
}

/*
const (

	red    = 31
	yellow = 32
	blue   = 33
	gray   = 34

)

	func (MyLog) Format(entry *logrus.Entry) ([]byte, error) {
		var levelColor int
		switch entry.Level {
		case logrus.DebugLevel, logrus.TraceLevel:
			levelColor = gray
		case logrus.WarnLevel:
			levelColor = yellow
		case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
			levelColor = red
		default:
			levelColor = blue
		}
		var b *bytes.Buffer
		if entry.Buffer != nil {
			b = entry.Buffer
		} else {
			b = &bytes.Buffer{}
		}
		// 自定义日期格式
		timestamp := entry.Time.Format("2006-01-02 15:04:05")

		// 检查是否有调用信息
		if entry.HasCaller() {
			// 自定义文件路径和函数信息
			funcVal := entry.Caller.Function
			fileVal := fmt.Sprintf("%s:%d", path.Base(entry.Caller.File), entry.Caller.Line)

			// 自定义输出格式
			fmt.Fprintf(b, "[%s] \x1b[%dm[%s]\x1b[0m %s %s %s\n", timestamp, levelColor, entry.Level, fileVal, funcVal, entry.Message)
		}

		return b.Bytes(), nil
	}
*/
func (MyLog) Format(entry *logrus.Entry) ([]byte, error) {
	var b *bytes.Buffer
	if entry.Buffer != nil {
		b = entry.Buffer
	} else {
		b = &bytes.Buffer{}
	}
	// 自定义日期格式
	timestamp := entry.Time.Format("2006-01-02 15:04:05")

	// 检查是否有调用信息
	if entry.HasCaller() {
		// 自定义文件路径和函数信息
		funcVal := entry.Caller.Function
		fileVal := fmt.Sprintf("%s:%d", path.Base(entry.Caller.File), entry.Caller.Line)

		// 自定义输出格式，去掉了颜色部分
		fmt.Fprintf(b, "[%s][%s] %s %s %s\n", timestamp, entry.Level, fileVal, funcVal, entry.Message)
	}

	return b.Bytes(), nil
}

func InitLogger() {
	logrus.SetLevel(logrus.InfoLevel)
	logrus.SetReportCaller(true)
	logrus.SetFormatter(MyLog{})
	logrus.AddHook(&MyHook{
		logPath: "logs",
	})

}

type MyHook struct {
	file    *os.File
	errFile *os.File
	date    string
	logPath string
	mu      sync.Mutex
}

func (m *MyHook) Fire(entry *logrus.Entry) error {
	m.mu.Lock()
	defer m.mu.Unlock()
	timer := entry.Time.Format("2006-01-02")
	line, err := entry.String()
	if err != nil {
		return fmt.Errorf("failed to format log entry: %v", err)
	}

	if m.date != timer {
		if err := m.rotateFiles(timer); err != nil {
			return err
		}
	}

	if _, err := m.file.Write([]byte(line)); err != nil {
		return fmt.Errorf("failed to write to log file: %v", err)
	}

	if entry.Level <= logrus.ErrorLevel {
		if _, err := m.errFile.Write([]byte(line)); err != nil {
			return fmt.Errorf("failed to write to error log file: %v", err)
		}
	}

	return nil
}
func (m *MyHook) rotateFiles(timer string) error {
	if m.file != nil {
		if err := m.file.Close(); err != nil {
			return fmt.Errorf("failed to close log file: %v", err)
		}
	}
	if m.errFile != nil {
		if err := m.errFile.Close(); err != nil {
			return fmt.Errorf("failed to close error log file: %v", err)
		}
	}

	dirName := fmt.Sprintf("%s/%s", m.logPath, timer)
	if err := os.MkdirAll(dirName, os.ModePerm); err != nil {
		return fmt.Errorf("failed to create log directory: %v", err)
	}

	infoFilename := fmt.Sprintf("%s/info.log", dirName)
	errFilename := fmt.Sprintf("%s/error.log", dirName)

	var err error
	m.file, err = os.OpenFile(infoFilename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600)
	if err != nil {
		return fmt.Errorf("failed to open log file: %v", err)
	}

	m.errFile, err = os.OpenFile(errFilename, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600)
	if err != nil {
		return fmt.Errorf("failed to open error log file: %v", err)
	}

	m.date = timer
	return nil
}
func (m *MyHook) Levels() []logrus.Level {
	return logrus.AllLevels
}
